#include "myLib.h"
#include "silib.h"
#include "startScreen.h"
#include <stdlib.h>

/*
Kyle Kelly
HW9
CS2110-B2
*/

Ship ship;
Invader invaders[INIT_INVADERS];
Invader oldInvaders[INIT_INVADERS];
Bullet invaderBullets[INIT_INVADERS];
int availableInvBullets = 5;
u32 lives = INIT_LIVES;
int invaderVel = 1;
int numInvaders = INIT_INVADERS;
extern const unsigned short startScreen[38400];

/*Progressing the game methods*/
void newGame()
{
	genInvaders();
	genShip();
	lives = INIT_LIVES;
	numInvaders = INIT_INVADERS;
	invaderVel = 1;
	drawRect(ship.r, ship.c, SHIPH, SHIPW, RGB(15,15,15));
	for(int i = 0; i< INIT_INVADERS; i++)
	{
		drawRect(invaders[i].r, invaders[i].c, INVADERH, INVADERW, RGB(0,31,0));
	}
}

void genShip()
{
    ship.r =  SPACESHIP_INIT_ROW;
	ship.c =  SPACESHIP_INIT_COL;
	ship.bulletsLeft = MAX_PLAYER_BULLETS;
	for (int i = 0; i<MAX_PLAYER_BULLETS; i++)
	{
	    ship.bullets[i].status = UNFIRED;
	}
	ship.status = ALIVE;
}

void genInvaders()
{
	int counter = 1;
	int curRow = 0;
	int curCol = 0;
	for( int i = 0; i < INIT_INVADERS; i++)
	{
		if((counter%INVADERS_PER_ROW) == 1)
		{
			curRow = curRow + 2;
			curCol = 0;
		}
		invaders[i].r = INVADER_START_R  + curRow*INVADERH;
		invaders[i].c = INVADER_START_C  + curCol*(INVADERW + INVADER_BUFFER) + 1;
		invaders[i].bullet.status = UNFIRED;
		invaders[i].status = ALIVE;
		counter++;
		curCol++;
		availableInvBullets = 5;
	}
}

int waitForStart()
{
    drawImage3(0, 0, STARTSCREEN_HEIGHT, STARTSCREEN_WIDTH, &startScreen[0]);
	int buttonWasPressed, counter;
	buttonWasPressed = 0;
	counter = 0;
    while(buttonWasPressed == 0)
    {
    	counter++;
        buttonWasPressed = KEY_PRESSED(BUTTON_START);
    }
    clearScreen();
    return counter;
}

void checkWinConditions()
{
    if(numInvaders == 0)
    {   
        clearScreen();
        while(1)
        {
            //display win screen
            drawImage3(0,0,WIN_HEIGHT, WIN_WIDTH, &win[0]);
            if(KEY_PRESSED(BUTTON_START))
            {
                break;
            }
        }
        clearScreen();
        newGame();
    }
}

void checkLoseConditions()
{
    if((lives ==0) || (invaders[INIT_INVADERS-1].r >= ship.r + SHIPH))
    {
        clearScreen();
        while(1)
        {
            //display lose screen
            drawImage3(0,0,LOSER_HEIGHT, LOSER_WIDTH, &loser[0]);
            if(KEY_PRESSED(BUTTON_START))
            {
            break;
            }
        }
        clearScreen();
        newGame();
    }
}

/*Movement methods*/
void moveLeft()
{
	if(ship.c >0 )
	{
		Ship oldShip = ship;
		--ship.c;
		drawRect(oldShip.r, oldShip.c, SHIPH, SHIPW, RGB(0,0,0));
		drawRect(ship.r, ship.c, SHIPH, SHIPW, RGB(15,15,15));
	}
}

void moveRight()
{
	if((ship.c+SHIPW) < SCREENW)
	{
		Ship oldShip = ship;
		++ship.c;
		drawRect(oldShip.r, oldShip.c, SHIPH, SHIPW, RGB(0,0,0));
		drawRect(ship.r, ship.c, SHIPH, SHIPW, RGB(15,15,15));
	}
}

/*Firing bullets methods*/

void invadersTryFire()
{
	int shooter = rand()%INIT_INVADERS;
	if((invaders[shooter].bullet.status == UNFIRED) && (rand()%50 == 0) && availableInvBullets && (invaders[shooter].status == ALIVE))
	{
        invaders[shooter].bullet.status = FIRED;
        invaders[shooter].bullet.r = invaders[shooter].r + INVADERH;
        invaders[shooter].bullet.c = invaders[shooter].c + (INVADERW/2);
        availableInvBullets--;
	}
}

void playerFire()
{   
    if(ship.bulletsLeft > 0)
    {
        for(int i = 0; i<MAX_PLAYER_BULLETS; i++)
        {   
            if(ship.bullets[i].status == UNFIRED)
            {
                ship.bullets[i].status = FIRED;
                ship.bullets[i].r = ship.r -BULLETHW;
                ship.bullets[i].c = ship.c+(SHIPW/2) ;
	            ship.bulletsLeft--;
	            break;
	        }
	    }
    }
}

void updateBullets()
{
	//UPDATES PLAYER'S BULLETS
    for (int i = 0; i < MAX_PLAYER_BULLETS; i++)
    {
        if(ship.bullets[i].status == FIRED)
        {   
            if(ship.bullets[i].r < 1)
            {
                ship.bullets[i].status = UNFIRED;
                drawRect(ship.bullets[i].r, ship.bullets[i].c, BULLETHW, BULLETHW, RGB(0,0,0));
                ship.bulletsLeft++;
            }
            else
            {
                drawRect(ship.bullets[i].r, ship.bullets[i].c, BULLETHW, BULLETHW, RGB(0,0,0));
                ship.bullets[i].r--;
                drawRect(ship.bullets[i].r, ship.bullets[i].c, BULLETHW, BULLETHW, RGB(31,31,31));
            }
		}
		else
		{	
			ship.bullets[i].r = 0;
			ship.bullets[i].c = 0;
		}
	}
	//UPDATES INVADERS' BULLETS
	for (int j = 0; j < INIT_INVADERS; j++)
	{
	    if(invaders[j].bullet.status == FIRED)
	    {
	        if(invaders[j].bullet.r > SCREENH)
	        {
	            invaders[j].bullet.status = UNFIRED;
	            drawRect(invaders[j].bullet.r, invaders[j].bullet.c, BULLETHW, BULLETHW, RGB(0,0,0));
	            availableInvBullets++;
	        }
	        else
	        {
	            drawRect(invaders[j].bullet.r, invaders[j].bullet.c, BULLETHW, BULLETHW, RGB(0,0,0));
	            invaders[j].bullet.r++;
                drawRect(invaders[j].bullet.r, invaders[j].bullet.c, BULLETHW, BULLETHW, RGB(31,0,0));
	        }
	    }
	}
}

/*UPDATE AND DRAW METHODS FOR INVADERS*/
void updateInvaders()
{	
	for(int i = 0; i< INIT_INVADERS; i++)
	{
		oldInvaders[i] = invaders[i];
	}
	/*This part updates their row*/
	if(((invaders[INVADERS_PER_ROW-1].c + INVADERW + INVADER_BUFFER) == SCREENW) ||
		((invaders[0].c  - INVADER_BUFFER) == 0))
	{
		for(int i = 0; i< INIT_INVADERS; i++)
		{
			invaders[i].r = invaders[i].r + INVADERH;
		}
		invaderVel = -invaderVel;
	}
	/*Updates their column*/
	for(int i = 0; i < INIT_INVADERS; i++)
	{
		invaders[i].c += invaderVel;
	}
}

void drawInvaders()
{
	for(int i = 0; i<INIT_INVADERS; i++)
	{
		if(invaders[i].status == ALIVE)
		{
			drawRect(oldInvaders[i].r, oldInvaders[i].c, INVADERH, INVADERW, RGB(0,0,0));
			drawRect(invaders[i].r, invaders[i].c, INVADERH, INVADERW, RGB(0,31,0));
		}
	}
}

/*Checks for collisions between bullets and enemy/player*/
void checkCollisions()
{   
    //start checking for your bullets to hit invaders
	for(int i = 0; i< MAX_PLAYER_BULLETS; i++)
	{
		for(int j = 0; j< INIT_INVADERS; j++)
		{
			if(ship.bullets[i].status == FIRED && invaders[j].status == ALIVE)
			{
				if((ship.bullets[i].r<=(invaders[j].r+INVADERH))&&(ship.bullets[i].r >= invaders[j].r))
				{
				    if((ship.bullets[i].c<= (invaders[j].c + INVADERW))&&(ship.bullets[i].c >= invaders[j].c))
				    {
						ship.bullets[i].status = UNFIRED;
						ship.bulletsLeft++;
						drawRect(invaders[j].r, invaders[j].c, INVADERH, INVADERW, RGB(0,0,0));
						drawRect(ship.bullets[i].r, ship.bullets[i].c, BULLETHW, BULLETHW, RGB(0,0,0));
						invaders[j].status = DEAD;
						numInvaders--;
					}
					else if(((ship.bullets[i].c+BULLETHW)>= invaders[j].c)&&((ship.bullets[i].c + BULLETHW)<=(invaders[j].c+INVADERW)))
				    {
			            ship.bullets[i].status = UNFIRED;
						ship.bulletsLeft++;
						drawRect(invaders[j].r, invaders[j].c, INVADERH, INVADERW, RGB(0,0,0));
						drawRect(ship.bullets[i].r, ship.bullets[i].c, BULLETHW, BULLETHW, RGB(0,0,0));
						invaders[j].status = DEAD;
						numInvaders--;
					}
				}
				else if(((ship.bullets[i].r+BULLETHW)<=(invaders[j].r+INVADERH))&&((ship.bullets[i].r+BULLETHW) >= invaders[j].r))
				{
				    if((ship.bullets[i].c<= (invaders[j].c + INVADERW))&&(ship.bullets[i].c >= invaders[j].c))
				    {
						ship.bullets[i].status = UNFIRED;
						ship.bulletsLeft++;
						drawRect(invaders[j].r, invaders[j].c, INVADERH, INVADERW, RGB(0,0,0));
						drawRect(ship.bullets[i].r, ship.bullets[i].c, BULLETHW, BULLETHW, RGB(0,0,0));
						invaders[j].status = DEAD;
						numInvaders--;
					}
					else if(((ship.bullets[i].c+BULLETHW)>= invaders[j].c)&&((ship.bullets[i].c+BULLETHW) <= (invaders[j].c+INVADERW)))
				    {
						ship.bullets[i].status = UNFIRED;
						ship.bulletsLeft++;
						drawRect(invaders[j].r, invaders[j].c, INVADERH, INVADERW, RGB(0,0,0));
						drawRect(ship.bullets[i].r, ship.bullets[i].c, BULLETHW, BULLETHW, RGB(0,0,0));
						invaders[j].status = DEAD;
						numInvaders--;
			        }
				}
			}
		}
	}
	//START CHECKING FOR BULLETS TO HIT PLAYER
	for(int i = 0; i < INIT_INVADERS; i++)
	{
	    if(invaders[i].bullet.status == FIRED)
	    {
	        if((invaders[i].bullet.r>=ship.r)&&(invaders[i].bullet.r<=(ship.r+SHIPH)))
	        {
	            if((invaders[i].bullet.c>=ship.c)&&(invaders[i].bullet.c<=(ship.c+SHIPW)))
	            {
	                drawRect(ship.r,ship.c,SHIPH, SHIPW,RGB(0,0,0));
	                drawRect(invaders[i].bullet.r, invaders[i].bullet.c, BULLETHW, BULLETHW, RGB(0,0,0));
	                ship.r = SPACESHIP_INIT_ROW;
	                ship.c = SPACESHIP_INIT_COL;
	                drawRect(ship.r, ship.c, SHIPH, SHIPW, RGB(15,15,15));
	                lives--;
	                invaders[i].bullet.status = UNFIRED; 
	            }
	            else if(((invaders[i].bullet.c+BULLETHW)>=ship.c)&&((invaders[i].bullet.c+BULLETHW)<=(ship.c+SHIPW)))
	            {
	                drawRect(ship.r,ship.c,SHIPH, SHIPW,RGB(0,0,0));
	                drawRect(invaders[i].bullet.r, invaders[i].bullet.c, BULLETHW, BULLETHW, RGB(0,0,0));
	                ship.r = SPACESHIP_INIT_ROW;
	                ship.c = SPACESHIP_INIT_COL;
	                drawRect(ship.r, ship.c, SHIPH, SHIPW, RGB(15,15,15));
	                lives--;
	                invaders[i].bullet.status = UNFIRED; 
	            }
	        }
	        else if(((invaders[i].bullet.r+BULLETHW)>=ship.r)&&((invaders[i].bullet.r+BULLETHW)<=(ship.r+SHIPH)))
	        {
	            if((invaders[i].bullet.c>=ship.c)&&(invaders[i].bullet.c<=(ship.c+SHIPW)))
	            {
	                drawRect(ship.r,ship.c,SHIPH, SHIPW,RGB(0,0,0));
	                drawRect(invaders[i].bullet.r, invaders[i].bullet.c, BULLETHW, BULLETHW, RGB(0,0,0));
	                ship.r = SPACESHIP_INIT_ROW;
	                ship.c = SPACESHIP_INIT_COL;
	                drawRect(ship.r, ship.c, SHIPH, SHIPW, RGB(15,15,15));
	                lives--;
	                invaders[i].bullet.status = UNFIRED; 
	            }
	            else if(((invaders[i].bullet.c+BULLETHW)>=ship.c)&&((invaders[i].bullet.c+BULLETHW)<=(ship.c+SHIPW)))
	            {
	                drawRect(ship.r,ship.c,SHIPH, SHIPW,RGB(0,0,0));
	                drawRect(invaders[i].bullet.r, invaders[i].bullet.c, BULLETHW, BULLETHW, RGB(0,0,0));
	                ship.r = SPACESHIP_INIT_ROW;
	                ship.c = SPACESHIP_INIT_COL;
	                drawRect(ship.r, ship.c, SHIPH, SHIPW, RGB(15,15,15));
	                lives--;
	                invaders[i].bullet.status = UNFIRED; 
	            }
	        }
	    }
	}
}
